﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Diagnostics;

namespace IcqSharp
{
    public class LocationFamilyHandler
    {
        public static void Handle(MemoryStream stream, SNACHeader header)
        {
            switch (header.Subtype)
            {
                case (UInt16)LocationFamilySubtype.RightsReply:
                    // Reply to CLI_REQLOCATION
                    // Server sent SNAC(x02,x03) - SRV_LOCATION_RIGHTS_REPLY
                    break;

                case (UInt16)LocationFamilySubtype.UserInfoReply: // AIM user info reply
                    HandleLocationUserInfoReply(stream, header); break;

                case (UInt16)LocationFamilySubtype.Error:
                    HandleLocationError(stream, header); break;

                default:
                    // NetLog_Server("Warning: Ignoring SNAC(x%02x,x%02x) - 
                    // Unknown SNAC (Flags: %u, Ref: %u)", ICQ_LOCATION_FAMILY, 
                    // pSnacHeader->wSubtype, pSnacHeader->wFlags, 
                    // pSnacHeader->dwRef);
                    break;
            }
        }

        public static void HandleLocationUserInfoReply(MemoryStream stream, SNACHeader header)
        {
            Log.Write("Got  Location.UserInfoReply");

            CookieMessageData CookieData;

            // Unpack the sender's user ID
            UInt32 uin; String uid;
            if (!Utilities.UnpackUID(stream, out uin, out uid))
                return;

            
            if (stream.Available() < 4) return;
            var WarningLevel = stream.ReadUInt16();  // Warning level?
            var TlvCount = stream.ReadUInt16();      // TLV count

            // Determine contact
            var contact = Contacts.Find(uin, uid);

            // Ignore away status if the user is not already on our list
            if (contact == null) return;

            var cookie = Cookies.FindCookie(header.Ref);
            if (cookie == null) {
                // Error: Received unexpected away reply from %s, strUID(dwUIN, szUID)
                Debugger.Break(); return; }

            CookieData = new CookieMessageData(cookie.Extra);

            ; //if (contact != cookie.Contact)
            //{
                // Error: Away reply Contact does not match Cookie Contact(0x%x != 0x%x), hContact, hCookieContact
                // ReleaseCookie(dwCookie); // This could be a bad idea, but I think it is safe
                // return;
            //}

            if (cookie.Type == (Byte)CookieType.FamilySpecial)
            {
                // ReleaseCookie(dwCookie);
                String about_msg = "";

                // Read user info TLVs
                        
                // Syntax check
                if (stream.Available() < 4) return;

                // Get general chain
                var chain = new TLVChain(stream, TlvCount);
                if (chain == null) return;

                // Get extra chain
                chain = new TLVChain(stream, 2);
                if (chain != null)
                {
                    //oscar_tlv* pTLV;
                    String encoding = null;

                    // Get Profile encoding TLV
                    var tlv = chain.Find(0x01, 1);
                    if (tlv != null && (tlv.Len >= 1))
                    {
                        encoding = tlv.Data.ToAsciiString();
                        encoding = encoding.Replace("charset=", "");
                    }

                    // Get Profile info TLV
                    tlv = chain.Find(0x02, 1);
                    if (tlv != null && (tlv.Len >= 1))
                    {
                        var enc = System.Text.Encoding.GetEncoding(Int32.Parse(encoding));
                        about_msg = enc.GetString(tlv.Data);
                        ; // msg = msg.EliminateHtml(...);
                    }
                }

                contact.About = about_msg;

                ; // BroadcastAck(hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, (HANDLE)1, 0);   
            }
            else
            {
                // away message

                ; // ! what status enum is used - Miranda or ICQ?
                var status = (UInt16)CookieData.AckType; // AwayMsgTypeToStatus(pCookieData->nAckType);
                if (status == (UInt16)IcqStatus.Offline)
                {
                    // NetLog_Server("SNAC(2.6) Ignoring unknown status message from %s", strUID(dwUIN, szUID));

                    //ReleaseCookie(dwCookie);
                    return;
                }

                //ReleaseCookie(dwCookie);

                // Read user info TLVs
                        
                //oscar_tlv_chain* pChain;
                //oscar_tlv* pTLV;
                //BYTE* tmp;
                //char* szMsg = NULL;
                //CCSDATA ccs;
                //PROTORECVEVENT pre;

                //// Syntax check
                //if (wLen < 4)
                //    return;

                //tmp = buf;
                //// Get general chain
                //if (!(pChain = readIntoTLVChain(&buf, wLen, wTLVCount)))
                //    return;

                //disposeChain(&pChain);

                //wLen -= (buf - tmp);

                //// Get extra chain
                //if (pChain = readIntoTLVChain(&buf, wLen, 2))
                //{
                //    char* szEncoding = NULL;

                //    // Get Away encoding TLV
                //    pTLV = pChain->getTLV(0x03, 1);
                //    if (pTLV && (pTLV->wLen >= 1))
                //    {
                //        szEncoding = (char*)_alloca(pTLV->wLen + 1);
                //        memcpy(szEncoding, pTLV->pData, pTLV->wLen);
                //        szEncoding[pTLV->wLen] = '\0';
                //    }
                //    // Get Away info TLV
                //    pTLV = pChain->getTLV(0x04, 1);
                //    if (pTLV && (pTLV->wLen >= 1))
                //    {
                //        szMsg = (char*)SAFE_MALLOC(pTLV->wLen + 2);
                //        memcpy(szMsg, pTLV->pData, pTLV->wLen);
                //        szMsg[pTLV->wLen] = '\0';
                //        szMsg[pTLV->wLen + 1] = '\0';
                //        szMsg = AimApplyEncoding(szMsg, szEncoding);
                //        szMsg = EliminateHtml(szMsg, pTLV->wLen);
                //    }
                //    // Free TLV chain
                //    disposeChain(&pChain);
                //}

                //ccs.szProtoService = PSR_AWAYMSG;
                //ccs.hContact = hContact;
                //ccs.wParam = status;
                //ccs.lParam = (LPARAM) & pre;
                //pre.flags = 0;
                //pre.szMessage = szMsg ? szMsg : (char*)"";
                //pre.timestamp = time(NULL);
                //pre.lParam = dwCookie;

                //CallService(MS_PROTO_CHAINRECV, 0, (LPARAM) & ccs);

                //SAFE_FREE((void**)&szMsg);
                        
                        
                    
            }
        
        }
        public static void HandleLocationError(MemoryStream stream, SNACHeader header)
        {
            //WORD wError;
            //HANDLE hCookieContact;
            //cookie_fam15_data* pCookieData;


            //var error = (stream.Available() >= 2) ?
            //    stream.ReadUInt16() : 0;

            //if (error == 4)
            //{
            //    var cookie = Cookies.FindCookie(header.Ref);

            //    //if (FindCookie(pSnacHeader->dwRef, &hCookieContact, (void**)&pCookieData) && !getContactUin(hCookieContact) && pCookieData->bRequestType == REQUESTTYPE_PROFILE)
            //    {
            //        //BroadcastAck(hCookieContact, ACKTYPE_GETINFO, ACKRESULT_FAILED, (HANDLE)1, 0);
            //        //ReleaseCookie(pSnacHeader->dwRef);
            //    }
            //}

            //// LogFamilyError(ICQ_LOCATION_FAMILY, wError);
        }
    }
}
